﻿using System;
using System.Threading;

namespace Hsenl {
    public class LogStopwatch {
        private string _stopwatchTitle;

        private DateTime _now;
        private string _accuracy;

        private long _avesum;
        private int _avecount;
        private long _max;
        private long _min;

        public long Ave => this._avecount == 0 ? 0 : this._avesum / this._avecount;

        public int AveCount => this._avecount;
        
        public long Max => this._max;
        public long Min => this._min;

        public LogStopwatch(string title, string accuracy = "f1") {
            this._stopwatchTitle = title;
            this._accuracy = accuracy;
            this._now = DateTime.Now;
            Log.Debug($"{title} (开始)");
        }

        public void Peek(string content) {
            Log.Debug($"{content} ({(DateTime.Now - this._now).TotalMilliseconds.ToString(this._accuracy)} ms)");
            this._now = DateTime.Now;
        }

        public void Peek(ref long tick) {
            tick = (DateTime.Now - this._now).Ticks;
            this._now = DateTime.Now;
        }

        public long Peek() {
            var ticks = (DateTime.Now - this._now).Ticks;
            this._now = DateTime.Now;
            return ticks;
        }

        public void PushAve(long value) {
            Interlocked.Add(ref this._avesum, value);
            Interlocked.Increment(ref this._avecount);
            if (value > this._max) {
                this._max = value;
            }

            if (value < this._min) {
                this._min = value;
            }
        }

        public long PeekAndPushAve() {
            var ticks = this.Peek();
            this.PushAve(ticks);
            return ticks;
        }

        public void ResetAve() {
            Interlocked.Exchange(ref this._avesum, 0);
            Interlocked.Exchange(ref this._avecount, 0);
            this._max = 0;
            this._min = long.MaxValue;
        }
    }
}